import { TRegisterKeyboardMap } from '../types/core.type';

/**
 * 注册的事件池
 */
class KeyboardPool {
	constructor() {}
	// 注册的键盘池
	private _keyboardPool: TRegisterKeyboardMap = {};

	// 锁住的事件
	private _lockKeyCodePool: string[] = [];

	/**
	 * 序列化key
	 * 将无顺序的key转为有序
	 * @param key
	 * @returns
	 */
	private parseKeyboardKey(key: string): string {
		const keyList = key.split('+');
		// 是否使用组合键
		if (!key.includes('+')) {
			return key.toUpperCase();
		}

		const resultKeyList: string[] = [];
		const sortIndexList = ['CTRL', 'SHIFT', 'ALT'];
		while (keyList.length > 0) {
			const key = (keyList.shift() as string).toUpperCase();

			// 如果是CTRL、SHIFT、ALT
			if (sortIndexList.includes(key)) {
				const index = sortIndexList.findIndex((k) => key === k);
				resultKeyList[index] = key;
			} else {
				resultKeyList.push(key);
			}
		}
		return resultKeyList.join('+');
	}

	// 是否存在
	has(key: string): boolean {
		return !!this._keyboardPool[key];
	}

	// 检测是否存在
	checkExist(key: string) {
		const keyCode = this.parseKeyboardKey(key);
		if (!this.getKeyboard(keyCode)) {
			console.warn(`[${key}] keyboard event is not defined yet`);
			return false;
		}
		return true;
	}

	// 设置池
	setKeyboard(key: string, callback: (event?: any) => void) {
		const parseKey = this.parseKeyboardKey(key);
		if (this._keyboardPool[parseKey]) {
			console.warn(`key=${key}已绑定，无法继续绑定！`);
			return;
		}
		this._keyboardPool[parseKey] = callback;
	}

	// 获取池
	getKeyboard(key: string) {
		const keyCode = this.parseKeyboardKey(key);
		return this._keyboardPool[keyCode];
	}

	// 锁定池
	lockKeyboard(key: string) {
		const keyCode = this.parseKeyboardKey(key);
		if (!this.checkExist(key)) {
			return;
		}
		this._lockKeyCodePool.push(keyCode);
		console.log(`[${key}] lock！`);
	}

	// 解锁池
	unLockKeyboard(key: string) {
		const keyCode = this.parseKeyboardKey(key);
		if (!this.checkExist(key)) {
			return;
		}
		const findIndex = this._lockKeyCodePool.findIndex((itm) => itm === keyCode);
		this._lockKeyCodePool.splice(findIndex, 1);
		console.log(`[${key}] Unlock！`);
	}

	// 是否锁定
	hasLock(key: string): boolean {
		return this._lockKeyCodePool.includes(key);
	}
}

export { KeyboardPool };
